﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace Intranet.Controllers
{
    [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)]
    sealed class MyAttribute : Attribute
    {
        // See the attribute guidelines at 
        //  http://go.microsoft.com/fwlink/?LinkId=85236
        readonly string positionalString;

        // This is a positional argument
        public MyAttribute(string positionalString)
        {
            this.positionalString = positionalString;

            // TODO: Implement code here
            throw new NotImplementedException();
        }

        public string PositionalString
        {
            get { return positionalString; }
        }

        // This is a named argument
        public int NamedInt { get; set; }
    }
    public class HomeController : IntranetController
    {
        private List<Models.activity> GetUserActivities(Guid user)
        {
            using (Models.intranetDBEntities entities = new Models.intranetDBEntities())
            {
                var acts = entities.activities.Where(p => p.assignedTo == user && !p.isDeleted);
                foreach (var item in acts)
                {
                    this.loadAll(item.activities1);
                    
                    //item.activityNotes.Load(); // no longer used
                }
                return acts.ToList();
            }
        }

        private void loadAll(System.Data.Objects.DataClasses.EntityCollection<Models.activity> entityCollection)
        {
            if (!entityCollection.IsLoaded)
            {
                entityCollection.Load();
            }
            foreach (var item in entityCollection)
            {
                if (item.parentId.HasValue)
                {
                    loadAll(item.activities1);
                }
            }
        }

        private Models.activity loadAll(Models.activity activity)
        {
            activity.activities1.Load();
            return activity;
        }

        public ActionResult AllActivities(IEnumerable<Models.activity> activities)
        {
            return PartialView(activities);
        }

        public ActionResult ParentActivity(Models.activity activity)
        {
            // TODO: Check user has permission to this activity            
            return PartialView(activity);
        }

        public ActionResult ChildActivities(IEnumerable<Models.activity> activities)
        {
            return PartialView(activities);
        }
        
        public ActionResult Index(long? id)
        {
            Views.ActivityStreamView view = new Views.ActivityStreamView();
                        
            Guid myUserId = base.RegisterOrAuthenticateUser(User.Identity);

            view.MyActivities = this.GetUserActivities(myUserId);

            if (id.HasValue)
            {
                view.MyActivities = view.MyActivities.Where(p => p.id == id.Value).ToList();
            }

            Models.activity activity = new Models.activity();
            activity.assignedTo = myUserId;
            view.NewActivity = activity;
            return View(view);
        }

        public ActionResult About()
        {
            return View();
        }

        //
        // GET: /Activities/Create
        [HttpGet]
        public ActionResult NewActivity()
        {
            Models.activity activity = new Models.activity();
            activity.assignedTo = base.RegisterOrAuthenticateUser(User.Identity);
            return PartialView(activity);
        }

        //
        // POST: /Activities/Create

        [HttpPost]
        public ActionResult NewActivity(FormCollection collection)
        {
            try
            {
                // TODO: Check the incoming user guid against the authenticated one, and refuse if they don't match
                Models.activity activity = new Models.activity();
                
                activity.createdDate = DateTime.Now;
                activity.dueDate = DateTime.Now.AddDays(1);
                activity.owner = Guid.Parse(collection["assignedTo"]);
                activity.assignedTo = activity.owner;
                activity.details = collection["NewActivity.details"];
                activity.parentId = Convert.ToInt64(collection["id"]);
                activity.isDeleted = false;
                createActivity(activity);
                
                Models.activity newActivity = new Models.activity();
                newActivity.assignedTo = activity.owner;
                
                return PartialView("AllActivities", GetUserActivities(activity.owner));
            }
            catch
            {
                return View();
            }
        }

        public ActionResult NewParentActivity(FormCollection collection)
        {
            try
            {
                Models.activity activity = new Models.activity();

                activity.createdDate = DateTime.Now;
                activity.dueDate = DateTime.Now.AddDays(1);
                activity.owner = Guid.Parse(collection["NewActivity.assignedTo"]);
                activity.assignedTo = activity.owner;
                activity.details = collection["NewActivity.details"];
                activity.parentId = null;
                activity.isDeleted = false;

                createActivity(activity);

                return PartialView("AllActivities", GetUserActivities(activity.owner));
            }
            catch
            {
                return View();
            }
        }

        private void createActivity(Models.activity activity)
        {
            using (Models.intranetDBEntities entities = new Models.intranetDBEntities())
            {
                entities.activities.AddObject(activity);
                entities.SaveChanges();
            }
        }

        public ActionResult Delete(long id)
        {
            using (Models.intranetDBEntities entities = new Models.intranetDBEntities())
            {
                if (entities.activities.Any(p => p.id == id))
                {
                    Models.activity activity = entities.activities.First(p => p.id == id);
                    
                    // any activities with this as the parent?  if so, prevent deletion...
                    if (entities.activities.Any(p => p.parentId == id && !p.isDeleted))
                    {
                        // TODO: handle events where activities have parents!
                        return View();
                    }
                    else
                    {
                        activity.isDeleted = true;
                        entities.SaveChanges();

                        //Guid myUserId = base.RegisterOrAuthenticateUser(User.Identity);
                        //List<Models.activity> myActivities = this.GetUserActivities(myUserId);
                        //var parentActivity = this.getTopParent(entities.activities.First(p => p.id == id), id);
                        //this.loadAll(parentActivity.activities1);
                        return PartialView("NULL");
                        //return PartialView("ParentActivity", parentActivity);
                    }
                }
                else
                {
                    return View();
                }
            }
        }

        private Models.activity getTopParent(Models.activity activityNode,long nodeId)
        {
            if (activityNode.parentId.HasValue)
            {
                return getTopParent(activityNode.activity1, nodeId);
            }
            else
            {
                return activityNode;
            }
        }

        public ActionResult AmendActivity(FormCollection collection)
        {
            DateTime newDate = DateTime.Parse(collection["dueDate"]);
            int id = Convert.ToInt32(collection["id"]);
            using (Models.intranetDBEntities entities=new Models.intranetDBEntities())
            {
                if (entities.activities.Any(p => p.id == id))
                {
                    Models.activity oldActivity = entities.activities.First(p => p.id == id);
                    TimeSpan oldDateTime = oldActivity.dueDate.TimeOfDay;
                    oldActivity.dueDate = newDate.Add(oldDateTime);
                    entities.SaveChanges();
                    return PartialView("ActivitySummary", oldActivity);
                }
                else
                {
                    return View();
                }
            }
            
        }

        public ActionResult ActivityDetails(long id)
        {
            using (Models.intranetDBEntities entities = new Models.intranetDBEntities())
            {
                if (entities.activities.Any(p => p.id == id))
                {
                    Views.ActivityDetailsView view = new Views.ActivityDetailsView();
                    view.Activity = entities.activities.First(p => p.id == id);
                    view.Activity.activityNotes.Load();
                    view.Activity.projectReference.Load();
                    


                    return View(view);
                }
                else
                {
                    return RedirectToAction("Index");
                }
            }
        }

        public ActionResult NewNote(FormCollection collection)
        {
            try
            {
                // TODO: Check the incoming user guid against the authenticated one, and refuse if they don't match
                Models.activityNote activityNote = new Models.activityNote();
                long id=Convert.ToInt64(collection["Activity.id"]);
                activityNote.addedBy = Guid.Parse(collection["Activity.assignedTo"]);
                activityNote.createdBy = activityNote.addedBy;
                activityNote.createdDate = DateTime.Now;
                activityNote.dueDate = activityNote.createdDate.Value.AddDays(1);
                activityNote.notes = collection["NewNotes.details"];
                activityNote.activityId = id;
                using (Models.intranetDBEntities entities = new Models.intranetDBEntities())
                {
                    int? order = entities.activityNotes.Max(p => p.order);
                    if (order.HasValue)
                    {
                        activityNote.order = order.Value + 1;
                    }
                    else
                    {
                        activityNote.order = 0;
                    }
                    
                    entities.activityNotes.AddObject(activityNote);
                    entities.SaveChanges();
                }

                return RedirectToAction("ActivityDetails", new { id = id });
            }
            catch
            {
                return View();
            }
        }

        [HttpGet]
        public ActionResult NoteDetail(long id)
        {
            using (Models.intranetDBEntities entities = new Models.intranetDBEntities())
            {
                if (entities.activityNotes.Any(p => p.id == id))
                {
                    Views.ActivityNoteDetailsView view = new Views.ActivityNoteDetailsView();
                    view.ActivityNote = entities.activityNotes.First(p => p.id == id);
                    view.ActivityId = view.ActivityNote.activityId.Value;
                    return View(view);
                }
                else
                {
                    // get previous page route id value and redirect back to activity details
                    return RedirectToAction("Details", new { id = ControllerContext.RequestContext.RouteData.Values["id"] });
                }
            }
        }
        
        [HttpPost]
        public ActionResult NoteDetail(long id, Views.ActivityNoteDetailsView note)
        {
            // TODO: Check the incoming user guid against the authenticated one, and refuse if they don't match
            using (Models.intranetDBEntities entities = new Models.intranetDBEntities())
            {
                if (entities.activityNotes.Any(p => p.id == id))
                {
                    
                    Models.activityNote oldNote= entities.activityNotes.First(p => p.id == id);
                    oldNote.dueDate = note.ActivityNote.dueDate;
                    oldNote.notes = note.ActivityNote.notes;
                    entities.SaveChanges();
                    return RedirectToAction("Details", new { id = note.ActivityId });
                }
                else
                {
                    // get previous page route id value and redirect back to activity details
                    return RedirectToAction("Details", new { id = ControllerContext.RequestContext.RouteData.Values["id"] });
                }
            }
        }

        [HttpPost]
        public ActionResult UpdateDate(FormCollection collection)
        {

            return View();
        }
    }
}
